<template>
  <!--
    v-model 是否处于下拉刷新加载中的状态，为布尔值；
    refresh 事件，下拉刷新时触发，同时将 v-model 值变为 true，开启下拉刷新加载的状态
  -->
  <van-pull-refresh class="home-main" v-model="refreshing" @refresh="onRefresh">
    <!-- 区域一：轮播图 -->
    <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
      <!-- 因为没有 id 属性，所以使用 index 绑定给 key -->
      <van-swipe-item
        v-for="(item, index) in swipeData"
        :key="index"
      >
        <img :src="item.img" alt="">
      </van-swipe-item>
    </van-swipe>
    <!-- 区域二：菜单列表，默认一行展示四个格子，可以通过 column-num 自定义列数 -->
    <van-grid icon-size="40px" :column-num="5">
      <van-grid-item
        v-for="(item, index) in menuData"
        :key="index"
        :icon="item.img"
        :text="item.info[0].value" />
    </van-grid>
    <!-- 区域三：公告栏区域，touchable 为 false，表示不可以上线滑动 -->
    <van-notice-bar left-icon="fire-o" :scrollable="false">
      <span>热点资讯公告：</span>
      <van-swipe
        vertical
        class="notice-swipe"
        :autoplay="3000"
        :touchable="false"
        :show-indicators="false"
      >
        <van-swipe-item
          v-for="(item, index) in newsData"
          :key="index"
        >
          <a :href="item.chiild[1].val">{{ item.chiild[0].val }}</a>
        </van-swipe-item>
      </van-swipe>
    </van-notice-bar>
    <!--
      区域四：商品列表，将商品列表数据传递给组件 ProductList.vue
      van-list 设置当列表即将滚动到底部时，会触发事件并加载更多列表项。
      v-model:loading 是否处于加载状态，加载过程中不触发 load 事件，默认值为 false，不处于加载状态。
      loading-text 加载过程中的提示文案。
      v-model:error 是否加载失败，加载失败后点击错误提示可以重新触发 load 事件，默认值为 false。
      error-text 加载失败后的提示文案。
      finished 是否已经加载完成，加载完成后不再触发 load 事件，默认值为 false，值为 true 表示加载完成。
      finished-text 加载完成后的提示文案。
      load 事件，商品列表滚动到底部触发 initProductsList 发送请求，并且会将 v-model:loading 设置为 true，开启加载状态。
    -->
    <van-list
      v-model:loading="loading"
      v-model:error="error"
      error-text="请求失败，点击重新加载"
      :finished="finished"
      finished-text="没有更多了"
      @load="initProductsList"
    >
      <ProductList :products-data="productsList" />
    </van-list>
  </van-pull-refresh>
</template>
<script setup>
import ProductList from '@/components/ProductList.vue'
import { ref, computed } from 'vue'
import { getDefaultData } from '@/api/home.js'
import { getProductsList } from '@/api/products.js'

/* -------- 获取首页信息 ---------- */
// 一、声明响应式数据，存储首页的所有数据
const homeData = ref({})
// 二、封装首页数据初始化的函数，为了页面首次加载数据和下拉刷新数据时使用
const initHomeData = async () => {
  const { data } = await getDefaultData()
  // 数据请求失败，返回
  if (data.status !== 200) return
  homeData.value = data.data
  // 数据请求成功后，关闭下拉刷新状态
  refreshing.value = false
  console.log(data)
}
initHomeData()

/*
三、因为 homeData 保存着首页的所有数据，嵌套层级比较多，如果直接使用 homeData 来获取轮播图的数据，太麻烦了
使用 computed 计算属性，按照不同功能保存需要的数据，数据渲染时简化了书写
*/
// 1. 获取轮播图数据
const swipeData = computed(() => homeData.value.swiperBg?.default.imgList.list)
// 2. 获取菜单列表数据
const menuData = computed(() => homeData.value.menus?.default.imgList.list)
// 3. 获取公告栏数据
const newsData = computed(() => homeData.value.news?.default.newList.list)

/* -------- 获取商品列表信息 ---------- */
// 声明响应式数据，存储商品列表信息
const productsList = ref([])
// 是否启动加载状态，默认不启动
const loading = ref(false)
// 是否开启错误提示状态，默认不启动
const error = ref(false)
// 是否开启数据加载完成状态，默认不启动
const finished = ref(false)
// 记录展示哪一页加载的数据，默认是第一页的数据
let page = 1
// 表示一次请求返回4条数据
const limit = 4
// 发送获取商品列表信息的请求函数
const initProductsList = async () => {
  // 1. 发送请求
  const { data } = await getProductsList({
    limit,
    page
  })
  // 2. 数据加载失败，开启错误状态
  if (data.status !== 200) {
    error.value = true
    return
  }
  console.log(data)
  // 3. 每次请求都是得到新的一段数据，需要将新数据追加到 productsList 数组中
  // data.data 是一个存放商品列表的数组，使用扩展符将数组展开，再追加到 productsList 数组中
  productsList.value.push(...data.data)

  // 4. 加载状态结束，才能将数据渲染出来
  loading.value = false
  // 5. 当此次数据条数小于 limit 时，数据全部加载完成
  if (data.data.length < limit) {
    finished.value = true
  }
  // 6. 变更页数，准备下次加载
  page++
}
// 使用 list 组件后，会自动根据触底情况加载首次数据以及后续数据，所以不需要单独执行方法 initProductsList()

/* ------ 下拉刷新，重新加载所有数据 -------- */
// 是否处于下拉刷新的状态，默认为 false 不启动
const refreshing = ref(false)
// 下拉刷新时 refresh 事件 触发的函数
const onRefresh = () => {
  // 1. 清空所有数据
  homeData.value = {}
  productsList.value = []
  // 2. 页数还原
  page = 1
  // 3. 触底加载的状态还原
  loading.value = false
  error.value = false
  finished.value = false
  // 4. 重新发送请求
  initHomeData()
  initProductsList()
}
</script>
<style lang="scss" scoped>
  .home-main {
    // 区域一：轮播图
    .my-swipe {
      img {
        // 图片的宽度必须设置为 100%，否则图片会有部分溢出到屏幕之外
        width: 100%;
        height: 170px;
        vertical-align: top;
      }
    }
    // 区域三：公告栏区域，使用 :deep 才能让 .van-notice-bar__content 设置的样式生效
    :deep(.van-notice-bar__content) {
      // 让文字可以水平排列，垂直方向居中
      display: flex;
      align-items: center;
      .notice-swipe {
        // 让滚动文字垂直方向居中
        height: 40px;
        line-height: 40px;
        a {
          color: var(--van-notice-bar-text-color);
        }
      }
    }
  }
</style>
